4

vue项目前后端分离,采用axios为异步请求的库,为了解决Rest接口访问的安全问题,需要在每次发送请求前在请求头设置一个token和签名,以在服务端根据token和签名对访问的合法性做校验。

在axios的请求拦截器做这个逻辑,具体代码如下。

    /**
 * http配置
 */

import axios from 'axios';

var timestamp = '';
var headtoken = '';
var sign = '';
var domain = '/bop-web';
var instance = axios.create();

function buildParamStr(param, timestamp, url, signtoken) {

  param["timestamp"] = timestamp;
  param["url"] = url;
  param["signtoken"] = signtoken;
  var keys = [];
  var paramstr = "";
  for (var paramkey in param) {
    keys.push(paramkey);
  }
  keys.sort();
  for (var i = 0; i < keys.length; i++) {
    var itemkey = keys[i];
    if (typeof(param[itemkey]) === 'object') {
      param[itemkey] = JSON.stringify(param[itemkey]);
    }
    if (i === keys.length - 1) {
      paramstr += itemkey + "=" + param[itemkey];
    } else {
      paramstr += itemkey + "=" + param[itemkey] + "&";
    }
  }
  // console.log(paramstr);
  return paramstr;
}
function bulidSign(paramdata, timestamp, url, signtoken) {
  var paramStr = buildParamStr(paramdata, timestamp, url, signtoken);
  delete paramdata.signtoken;
  delete paramdata.timestamp;
  delete paramdata.url;
  var hash = CryptoJS.SHA256(paramStr);
  // console.log(hash.toString());
  return hash.toString();
}
function getToken() {
  return instance({url: '/token/getToken', type: 'get'});
}

// 超时时间
axios.defaults.timeout = 5000;

axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

axios.interceptors.response.use((res) => {
  if(res.headers.sessionstatus === 'timeout') {
    var url = btoa(window.location.href);
    window.location.href = domain + "/login/logindo?r=" + url;
  }
  return res;
}, (error) => {
   console.log(axios.interceptors.response);
  
  return Promise.reject(error);
});


axios.interceptors.request.use(
  config => {
    **return getToken().then((res) => {
      console.log('gettoken done');
      config = config ? config : {};
      config.params = config.params ? config.params : {};
      timestamp = res.data.data.timestamp;
      headtoken = res.data.data.headtoken;
      sign = bulidSign(config.params, res.data.timestamp, config.url, res.data.signtoken);
      config.headers = {
        timestamp: timestamp,
        headtoken: headtoken,
        sign: sign
      };
      return config;**
    }).catch((res) => {
      console.log(res);
    });
}, error => {
  Message.error({
    message: '加载超时'
  });
  return Promise.reject(error)
});

export default axios

penjoyer
126 声望9 粉丝

你的B计划是什么?